import { Component, OnInit } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd/message';
import { DatePipe } from '@angular/common';
import { NzModalService } from 'ng-zorro-antd/modal';
import { ActivatedRoute } from '@angular/router';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';

import { storageDeliveryMethodArrs } from '../../xstorage-manage-pipes/storage-manage-z.pipe';
import { CommonService } from '../../../../services-common/common.service';
import { PermissionService } from '../../../../service/permission.service';
import { StorageCommonService } from '../../xstorage-manage-services/storage-common.service';
import { StorageManageStockService } from '../../xstorage-manage-services/storage-manage-stock.service';
import { ExwarehousmanageService } from '../../xstorage-manage-services/exwarehous-manage.service';


@Component({
  selector: 'app-storage-exwarehous-handle',
  templateUrl: './storage-exwarehous-handle.component.html',
  styleUrls: ['./storage-exwarehous-handle.component.scss']
})
export class StorageExwarehousHandleComponent implements OnInit {

  routeParams: any = {};
  detailsData: any = {};

  exwarehousTableData: any[] = [];

  outTypeOptions: any[] = []; // 出库类型options
  locationOptions: any[] = []; // 库位Option
  warehouseOptions: any[] = []; // 仓库
  supplierOptions: any[] = []; // 供应商
  logisticsOptions: any[] = []; // 物流options

  modalInfoItems: any = {};
  submitLoading = false;

  /**
   * 选择SN Modal
   * ----------------------------------------------------------------
   */
  isSnVisible = false;
  snItemArrs: any[] = [];
  snGoodsItem: any = {};
  snGoodsModalItem: any = {};

  /**
   * 多库位 Modal
   * ----------------------------------------------------------------
   */
  isDkwVisible = false;
  moreLocationTable: any[] = [];

  /**
   * 指定SN信息 Modal
   * ----------------------------------------------------------------
   */
  isZdsnVisible = false;
  zdSnInfoTable: any[] = [];

  /**
   * 配送方式修改 Modal
   * ----------------------------------------------------------------
   */
  isDeliveryVisible = false;
  modifyDeliveryLoading = false;
  deliveryOptions: any[] = [...storageDeliveryMethodArrs];
  validateDeliveryForm!: FormGroup;

  constructor(
    private msg: NzMessageService,
    private activatedRoute: ActivatedRoute,
    private modal: NzModalService,
    private fb: FormBuilder,
    private commonService: CommonService,
    public permission: PermissionService,
    private storageCommonService: StorageCommonService,
    private storageManageStockService: StorageManageStockService,
    private services: ExwarehousmanageService
  ) {
    activatedRoute.queryParams.subscribe((res: any) => {
      this.routeParams = res || {};
    })
  }

  ngOnInit(): void {
    this.loadStoreOptions();
    this.loadSupplierList();
    this.loadOutTypeOptions();
    this.loadLogisticsData();

    this.loadDetailData();
    this.validateDeliveryForm = this.fb.group({
      isFreight: ['', [Validators.required]], // 运费承担
      deliveryMethod: ['', [Validators.required]], // 配送方式
      expressCode: [''], // 物流公司
      expressNo: [''], // 物流单号
      expressPrice: [''] // 运费
    });
  }

  // 查询物流
  async loadLogisticsData() {
    const res: any = await this.commonService.getDictList('logistics_company');
    this.logisticsOptions = (res && res.length) ? res : [];
  }

  // 查询仓库Options
  async loadStoreOptions() {
    let params = {
      page: 1,
      pageSize: 1000
    }
    const {code, data, message}: any = await this.storageCommonService.getWarehouseList(params);
    if (code === 0) {
      this.warehouseOptions = data.records || [];
    } else {
      this.msg.error(message);
    }
  }

  // 查询供应商
  async loadSupplierList() {
    const res: any = await this.commonService.getSupplierList();
    // 状态为正常de
    this.supplierOptions = res || [];
  }

  // 出库类型options
  async loadOutTypeOptions() {
    const res: any = await this.commonService.getDictList('outbound_type');
    this.outTypeOptions = res || [];
  }

  // 查询库位Options
  async loadLocationOptions() {
    let params = {
      whId: !this.commonService.isEmpty(this.detailsData.whId) ? this.detailsData.whId : '',
      page: 1,
      pageSize: 1000
    }
    const {code, data, message}: any = await this.storageCommonService.getLocationList(params);
    if (code === 0) {
      this.locationOptions = data.records || [];
    } else {
      this.msg.error(message);
    }
  }

  async loadDetailData() {
    let params = {
      id: this.routeParams.id
    }
    const msgId = this.msg.loading('数据加载中..', { nzDuration: 0 }).messageId;
    const {code, data}: any = await this.services.getExwarehousDetailData(params);
    this.msg.remove(msgId);

    if (code === 0) {
      const { delivery, list } = data || {};

      // 指定SN 设置实际出库数
      if (list && list.length) {
        list.forEach((item: any) => {
          // 指定SN
          if (item.type === 0) {
            item.actualNumber = item.itemSns ? (JSON.parse(item.itemSns)).length : 0;
          }
        });
      }

      this.detailsData = delivery || {};
      this.exwarehousTableData = list || [];

      this.loadLocationOptions();
    }
  }

  /**
   * 选择sn信息 Modal 组件
   * ----------------------------------------------------------------
   */
  showSnInfoModal(item: any) {
    this.snGoodsItem = {
      whGoodsId: item.whGoodsId,
      goodsCode: item.whGoodsCode || '', // 商品编码
      whId: this.detailsData.whId, // 仓库
      quality: item.quality, // 品质
      number: item.number || '' // 预计出库数量
    };;
    this.snGoodsModalItem = {
      goodsCode: item.whGoodsCode,
      whId: this.detailsData.whId || '',
      quality: this.detailsData.quality,
      number: item.number
    };
    this.snItemArrs = !this.commonService.isEmpty(item.itemSns) ? JSON.parse(item.itemSns) : [];
    this.isSnVisible = true;
  }

  appointSnData(val: any) {
    let setIndex = this.exwarehousTableData.findIndex(item => item.whGoodsId === this.snGoodsItem.whGoodsId);
    this.exwarehousTableData[setIndex].itemSns = val.itemSns;
    this.exwarehousTableData[setIndex].actualNumber = val.selectedArrs.length;
    // this.exwarehousTableData[setIndex].type = 1; // type  0 指定SN 1SN管控 2多库位 3普通
    this.exwarehousTableData[setIndex].isSnOpera = 1;
  }

  clearSnData(val: any) {
    let setIndex = this.exwarehousTableData.findIndex(item => item.whGoodsId === this.snGoodsItem.whGoodsId);
    this.exwarehousTableData[setIndex].itemSns = '';
    this.exwarehousTableData[setIndex].actualNumber = '';
    this.exwarehousTableData[setIndex].isSnOpera = 0;
  }

  /**
   * 多库位 Modal
   * ----------------------------------------------------------------
   */
  async loadDkwTableData() {
    let params = {
      goods: this.modalInfoItems.whGoodsCode || '',
      quality: this.detailsData.quality,
      whId: this.detailsData.whId,
      page: 1,
      pageSize: 99999,
    }
    const {code, data, message}: any = await this.storageManageStockService.getStockLocationList(params);

    if (code === 0) {
      const {list} = data || {};
      this.moreLocationTable = list.records || [];

      let arrs = !this.commonService.isEmpty(this.modalInfoItems.libraryText) ? JSON.parse(this.modalInfoItems.libraryText) : [];
      if (arrs.length) {
        this.moreLocationTable.forEach(item => {
          let tmpObj = arrs.find((ele: any) => ele.id === item.id);
          item.num = tmpObj.num || '';
        })
      }
    } else {
      this.msg.error(message);
    }
  }

  showMoreLocationModal(item: any) {
    this.modalInfoItems = item;
    this.loadDkwTableData();
    this.isDkwVisible = true;
  }

  subSelectedLocation() {
    let tmpNum = this.moreLocationTable.reduce((total: number, item: any) => {
      return total + (item.num || 0);
    }, 0);
    if (tmpNum > this.modalInfoItems.number) {
      this.msg.warning(`出库数量不能大于预计数量${this.modalInfoItems.number}`);
      return
    }
    
    let setArrs = this.moreLocationTable.map(ele => {
      return {
        id: ele.id,
        libraryId: ele.libraryId, // 出库库位
        num: ele.num || '' // 出库数量 实际
      }
    })
    let setIndex = this.exwarehousTableData.findIndex((item: any) => item.id === this.modalInfoItems.id);
    this.exwarehousTableData[setIndex].libraryText = setArrs.length ? JSON.stringify(setArrs) : '';
    this.exwarehousTableData[setIndex].actualNumber = tmpNum;
    this.isDkwVisible = false;
  }

  /**
   * 指定SN信息 Modal
   * ----------------------------------------------------------------
   */
  showAppointInfoModal(item: any) {
    this.modalInfoItems = item;
    this.zdSnInfoTable = !this.commonService.isEmpty(item.itemSns) ? JSON.parse(item.itemSns) : [];
    this.isZdsnVisible = true;
  }

  /**
   * 修改配送方式 Modal
   * ----------------------------------------------------------------
   */
  showEditDeliveryModal() {
    // 如果配送方式 = 系统自动下单，并且物流单号不为空
    if (this.detailsData.deliveryMethod === 1 && !this.commonService.isEmpty(this.detailsData.expressNo)) {
      this.msg.warning('请先取消物流单');
      return
    }
    this.validateDeliveryForm.reset();

    this.validateDeliveryForm.patchValue({
      isFreight: this.detailsData.isFreight, // 运费承担
      deliveryMethod: this.detailsData.deliveryMethod, // 配送方式
      expressCode: this.detailsData.expressCode, // 物流公司code
      expressNo: this.detailsData.expressNo, // 物流单号
      expressPrice: this.detailsData.expressPrice || '' // 运费
    })
    
    this.deliveryChange(this.detailsData.deliveryMethod);
    this.isDeliveryVisible = true;
  }

  deliveryChange(val: any) {
    this.validateDeliveryForm.get('expressCode')?.setValue('');
    
    // (系统下单 | 手动下单), 物流公司 必填
    if ([1, 2].includes(val)) {
      this.validateDeliveryForm.get('expressCode')!.setValidators(Validators.required);
      this.validateDeliveryForm.get('expressCode')!.markAsDirty();
    } else {
      this.validateDeliveryForm.get('expressCode')!.clearValidators();
      this.validateDeliveryForm.get('expressCode')!.markAsPristine();
    }

    // 手动下单，物流单号 必填
    if (val === 2) {
      this.validateDeliveryForm.get('expressNo')!.setValidators(Validators.required);
      this.validateDeliveryForm.get('expressNo')!.markAsDirty();
    } else {
      this.validateDeliveryForm.get('expressNo')!.clearValidators();
      this.validateDeliveryForm.get('expressNo')!.markAsPristine();
    }

    ['expressCode', 'expressNo'].forEach(key => {
      this.validateDeliveryForm.get(key)!.updateValueAndValidity();
    })

    // 系统下单, 物流单号 & 运费 清空
    if (val === 1) {
      this.validateDeliveryForm.patchValue({
        expressNo: '',
        expressPrice: ''
      });
    }

    // 线下配送, 物流公司 & 物流单号 清空
    if (val === 3) {
      this.validateDeliveryForm.patchValue({
        expressCode: '',
        expressNo: ''
      });
    }

    // (动态设置)物流单号Input设置禁用
    if ([1, 3].includes(val)) {
      this.validateDeliveryForm.controls.expressNo.disable();
    } else {
      this.validateDeliveryForm.controls.expressNo.enable();
    }
  }

  async subEditDeliveryData() {
    if (this.validateDeliveryForm.valid) {
      let logisticsObj = this.logisticsOptions.find(ele => ele.content == this.validateDeliveryForm.value.expressCode);
      let params = {
        updateType: 1, // 1 修改配送信息 2 修改仓库 3 修改收货人信息 4 取消物流单
        delivery: {
          id: this.routeParams.id,
          ...this.validateDeliveryForm.value,
          expressName: logisticsObj?.name || '', // 物流公司名
          expressNo: this.validateDeliveryForm.value.expressNo || '' // 物流单号
        }
      }
      // return
      this.modifyDeliveryLoading = true;
      const {code, message}: any = await this.services.updateDeliveryOrderInfoData(params);
      this.modifyDeliveryLoading = false;
  
      if (code === 0) {
        this.isDeliveryVisible = false;
        this.loadDetailData();
      } else {
        this.msg.error(message);
      }
    } else {
      Object.values(this.validateDeliveryForm.controls).forEach(control => {
        if (control.invalid) {
          control.markAsDirty();
          control.updateValueAndValidity({ onlySelf: true });
        }
      });
    }
  }

  /**
   * 暂存
   * ----------------------------------------------------------------
   */
  async subTemporaryStorage() {
    let arrs = this.exwarehousTableData.map(item => {
      return {
        isSnOpera: item.isSnOpera ? item.isSnOpera : 0, // 是否指定sn 0：否 1：是
        whGoodsId: item.whGoodsId,
        state: item.lineState, // 状态 0正常(新增默认) 1已作废
        type: item.type,  // 商品列表type为分类 (注: 选择SN则为指定sn) // type: 0 指定SN 1SN管控 2多库位 3普通(新增默认)
        number: item.number, // 预计出库数量
        price: item.price, // 出库单价
        closeRemark: !this.commonService.isEmpty(item.closeRemark) ? item.closeRemark : '', // 关闭备注
        actualNumber: !this.commonService.isEmpty(item.actualNumber) ? item.actualNumber : '', // 实际出库数量
        itemSns: !this.commonService.isEmpty(item.itemSns) ? item.itemSns : '', // 商品SN号列表
        libraryText: !this.commonService.isEmpty(item.libraryText) ? item.libraryText : '', // 库位信息
        libraryId: !this.commonService.isEmpty(item.libraryId) ? item.libraryId : '' // 库位id
      }
    })

    let params: any = {
      isSplit: 0, // 0：添加、1：拆单
      delivery: {
        id: this.routeParams.id
      },
      list: arrs
    }
    // return

    this.submitLoading = true;
    const {code, message}: any = await this.services.updateExwarehousData(params, 1);
    this.submitLoading = false;

    if (code === 0) {
      this.msg.success('操作成功');
      this.loadDetailData();
    } else {
      this.msg.error(message);
    }
  }

  /**
   * 打包完成
   * ----------------------------------------------------------------
   */
  batchPackOver() {
    let isPackOver = this.exwarehousTableData.filter(ele => ele.lineState === 0).some(item => {
      return this.commonService.isEmpty(item.actualNumber) || item.actualNumber == 0;
    })
    if (isPackOver && this.exwarehousTableData.length) {
      this.msg.warning('出库明细中存在实际出库数量未填写项');
      return
    }

    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '确认打包完成?',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        let params = {
          ids: [this.routeParams.id],
          state: 4,
          note: ''
        }
    
        const {code, data, message}: any = await this.services.auditExwarehousData(params);
        if (code === 0) {
          this.msg.success(data);
          this.loadDetailData();
        } else {
          this.msg.error(message);
        }
      },
      nzCancelText: '取消'
    });
  }

  /**
   * 通知快递取件
   * @returns 
   */
  noticeTakeParts() {
    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '确认通知快递取件?',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        let params = {
          ids: [this.routeParams.id]
        }
    
        const {code, data, message}: any = await this.services.notifyPickupData(params);
        if (code === 0) {
          this.msg.success(data);
          this.loadDetailData();
        } else {
          this.msg.error(message);
        }
      },
      nzCancelText: '取消'
    });
  }

  /**
   * 确认出库
   * ----------------------------------------------------------------
   */
  confirmExwarehousNum() {
    // 如果配送方式 = 系统自动，并且物流单号为空，则提示“是否通知快递公司取件？”点击是以后调用通知取件接口
    if (this.detailsData.deliveryMethod === 1 && this.commonService.isEmpty(this.detailsData.expressNo)) {
      this.modal.confirm({
        nzTitle: '提示',
        nzContent: '是否通知快递公司取件?',
        nzOnOk: () => {
          this.noticeTakeParts();
        }
      });
      return
    }

    // 如果配送方式 = 手动发货，并且物流单号为空，则提示“请完善物流信息”，然后弹出“修改配送方式”的弹窗；
    if (this.detailsData.deliveryMethod === 2 && this.commonService.isEmpty(this.detailsData.expressNo)) {
      this.modal.confirm({
        nzTitle: '提示',
        nzContent: '请完善物流信息',
        nzOnOk: () => {
          this.showEditDeliveryModal();
        }
      });
      return
    }

    let tmpArrs = this.exwarehousTableData.filter(ele => ele.lineState === 0 && ele.type !== 0 && ele.number != ele.actualNumber);

    let tipStr = `${tmpArrs.length > 0 ? `有<b>${tmpArrs.length}</b>个商品的实际出库数量和预计出库数量不一致，` : ''}确认发货数量不一致吗？`;

    if (tmpArrs.length > 0) {
      this.modal.confirm({
        nzTitle: '提示',
        nzContent: tipStr,
        nzOkText: '确认',
        nzOkType: 'primary',
        nzOkDanger: true,
        nzOnOk: async () => {
          this.subExwarehouseData();
        },
        nzCancelText: '取消'
      });
    } else {
      this.subExwarehouseData();
    }
  }

  subExwarehouseData() {
    this.modal.confirm({
      nzTitle: '提示',
      nzContent: '确认商品已被拿走了吗？该操作不可逆，是否继续出库？',
      nzOkText: '确认',
      nzOkType: 'primary',
      nzOkDanger: true,
      nzOnOk: async () => {
        let params = {
          ids: [this.routeParams.id],
          state: 5,
          note: ''
        }
    
        const {code, data, message}: any = await this.services.auditExwarehousData(params);
        if (code === 0) {
          this.msg.success(data);
          this.loadDetailData();
        } else {
          this.msg.error(message);
        }
      },
      nzCancelText: '取消'
    });
  }

  /**
   * other
   * ----------------------------------------------------------------
   */

  // 合计
  calcSumTotal(key: string) {
    let sum = 0;
    const calcArrs = this.exwarehousTableData.filter(ele => ele.lineState === 0);
    sum = calcArrs.reduce((total: number, item: any) => {
      return (total || 0) + (item[key] || 0);
    }, 0);

    return isNaN(sum) ? 0 : sum;
  }

  // 实际出库数合计
  actualTotal() {
    let sum = 0;
    const calcArrs = this.exwarehousTableData.filter(ele => ele.lineState === 0);
    sum = calcArrs.reduce((total: number, item: any) => {
      let itemNumber = 0;
      if (!this.commonService.isEmpty(item.itemSns)) {
        itemNumber = JSON.parse(item.itemSns).length || 0;
      } else if (!this.commonService.isEmpty(item.libraryText)) {
        itemNumber = JSON.parse(item.libraryText).reduce((total: number, tag: any) => {
          return total + (tag.num || 0);
        }, 0);
      } else {
        itemNumber = (item.actualNumber || 0);
      }

      return (total || 0) + (itemNumber || 0);
    }, 0);

    return isNaN(sum) ? 0 : sum;
  }

  // Filter Text
  filterText(arrs: Array<any>, keyVal: any, idKey: string) {
    let tempObjs: any = {};
    if (arrs.length) {
      tempObjs = arrs.find(item => item[idKey] == keyVal);
    }

    return tempObjs?.name || '-';
  }

  coprText(str: any) {
    this.commonService.copyStr(str);
  }

  pageBack() {
    history.back();
  }

  // 批量库位
  batchLocationChange(val: any) {
    this.exwarehousTableData.forEach((item: any) => {
      // 行状态不为作废 | type 不等于 SN管控、多库位
      if (item.lineState !== 1 && ![0, 1, 2].includes(item.type)) {
        item.libraryId = val;
      }
    })
  }

  itemSnsTextStr(arrs: any) {
    let tempArrs: any =  arrs ? JSON.parse(arrs) : [];
    if (tempArrs?.length) {
      return `${ tempArrs.length }个指定SN`;
    } else {
      return '-';
    }
  }

  libraryTextStr(item: any) {
    let sum = 0;
    let tempArrs: any = !this.commonService.isEmpty(item.libraryText) ? (JSON.parse(item.libraryText)).filter((tag: any) => tag.num) : [];

    if (tempArrs?.length && item.actualNumber > 0) {
      sum = tempArrs.reduce((total: number, ele: any) => {
        return total + (ele.num || 0);
      }, 0);

      return `${ tempArrs.length }个库位共${ sum }件`;
    } else {
      return '请选择';
    }
  }
}
